route.ts 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. import { NextRequest, NextResponse } from 'next/server';
  2. import { ResultDto } from '@/types/response/common';
  3. import { LoginResponse } from '@/types/response/auth';
  4. import { fetchJson } from '@/lib/utils/server';
  5. export async function GET(request: NextRequest, { params }: { params: Promise<{ path: string[] }> })
  6. {
  7. const { path } = await params;
  8. const searchParams = request.nextUrl.searchParams.toString();
  9. const endpoint = `/api/auth/${path.join('/')}${searchParams ? `?${searchParams}` : ''}`;
  10. const res: ResultDto = await fetchJson(endpoint, {
  11. method: 'GET'
  12. });
  13. return NextResponse.json(res);
  14. }
  15. export async function POST(request: NextRequest, { params }: { params: Promise<{ path: string[] }> })
  16. {
  17. const { path } = await params;
  18. const endpoint = `/api/auth/${path.join('/')}`;
  19. let body: Record<string, unknown>|null = null;
  20. if (request.headers.get('content-type')?.includes('application/json')) {
  21. body = await request.json();
  22. }
  23. // refresh-token 은 클라이언트에서 httpOnly 쿠키를 읽을 수 없으므로
  24. // 라우트 핸들러가 쿠키의 refreshToken 을 body 로 자동 주입
  25. if (path[0] === 'refresh-token' && !body) {
  26. const rt = request.cookies.get('refreshToken')?.value;
  27. if (rt) {
  28. body = { RefreshToken: rt };
  29. }
  30. }
  31. const res: ResultDto = await fetchJson(endpoint, {
  32. method: 'POST',
  33. ...(body && { body: JSON.stringify(body) })
  34. });
  35. const response = NextResponse.json(res);
  36. // 로그인 또는 토큰 갱신 성공 시 쿠키 설정
  37. if ((path[0] === 'login' || path[0] === 'google-login' || path[0] === 'refresh-token') && res.success && res.data) {
  38. const data = res.data as LoginResponse;
  39. // RefreshToken TTL(백엔드 7일) 에 맞춤. accessToken 자체 exp 는 짧지만 쿠키 수명은 refresh 와 동일하게 잡아 OS 슬립/탭 재개 후에도 세션 유지.
  40. const sevenDaysSec = 7 * 24 * 60 * 60;
  41. const cookieOptions = {
  42. httpOnly: true,
  43. path: '/',
  44. sameSite: 'lax' as const,
  45. secure: process.env.NODE_ENV === 'production',
  46. maxAge: sevenDaysSec
  47. };
  48. response.cookies.set('accessToken', data.accessToken, cookieOptions);
  49. response.cookies.set('refreshToken', data.refreshToken, cookieOptions);
  50. }
  51. if (path[0] === 'logout') {
  52. response.cookies.delete('accessToken');
  53. response.cookies.delete('refreshToken');
  54. }
  55. return response;
  56. }